home *** CD-ROM | disk | FTP | other *** search
/ Hottest 6 / Hottest 6 (1996)(PDSoft)[!].iso / software / programming / c / shadow / docs / shadowlibrarymethods.doc < prev    next >
Text File  |  1978-11-24  |  100KB  |  2,328 lines

  1.                        Shadow.library  Documentation
  2.                             Library Version 5.0
  3.  
  4.                               By David Navas
  5.                          Updated:  13 Nov 1992
  6.  
  7.                       Copyright © 1992 by David Navas
  8.                             All Rights Reserved
  9.  
  10. Method definition for the following classes as defined in SHADOW 5.0:
  11.       DirectorClass
  12.       MetaClass
  13.       MetaCluster
  14.       PatcherClass
  15.       ProcessClass
  16.       RootClass
  17.       RootCluster
  18.  
  19.  
  20. What this document describes:
  21.  
  22.    This document is meant to be a reference appendix much in the same way
  23.    that Appendix B in the RKM:Libraries 3rd edition (ISBN 0-201-56774-1)
  24.    is for BOOPSI.  If you have not read either Chapter 12 of the
  25.    RKM:Libraries ("BOOPSI -- Object-Oriented Intuition"), or Appendix B
  26.    ("BOOPSI Class Reference"), it is highly recommended that you peruse
  27.    them.  Although SHADOW's object-oriented implementation is slightly
  28.    different than BOOPSI's, this reference attempts to mimic the RKM
  29.    layout as much as is reasonably feasible, and much common ground can
  30.    be found between the two.
  31.  
  32.    Where BOOPSI is intended to address the needs of Intuition, SHADOW
  33.    attempts to address a more comprehensive superset of needs.  As
  34.    such, while programming SHADOW is rather simple, understanding it
  35.    in its entirety can be intimidating.
  36.  
  37.    This document does not profess to be an exhaustive overview of SHADOW
  38.    itself.  Instead, its intent is to inform potential programmers of the
  39.    nuances of each of the individual method calls within each of the
  40.    available default classes.
  41.  
  42.  
  43. OVERVIEW and REVIEW:
  44.  
  45.    In SHADOW's version of the Object-Oriented Programming model, as with
  46.    BOOPSI's version, everything is an OBJECT.  In particular, under SHADOW,
  47.    everything that deals with the Object-Oriented part of SHADOW begins
  48.    with the structure CoreObject [include:shadow/core.h] which is defined
  49.    as being a combination of the OBJECT's cob_class and its cob_useCount.
  50.  
  51.    The cob_useCount of an OBJECT is used for resource tracking.  For the
  52.    most part, in order to deal with this document, the cob_useCount is
  53.    not required to be fully understood.  A broader discussion of it is
  54.    available elsewhere.  All interaction with this field MUST proceed
  55.    via the DropObject() and UseObject() calls and the CheckUseCount()
  56.    macro.
  57.  
  58.    The cob_class field is defined to be the "blueprints" of an object.
  59.    The object's ATTRIBUTEs (alternatively referred to as properties or
  60.    instance variables in other Object-Oriented Programming Models) and the
  61.    object's METHODs (alternatively referred to as functions in other
  62.    programming models) are all described in the OBJECT's cob_class.
  63.  
  64.    [Special note:
  65.       If an OBJECT's cob_class is NULL, the longword after the CoreObject
  66.       is assumed to contain the size of the object so that the OBJECT
  67.       can be freed when the cob_useCount drops to zero during a
  68.       DropObject() call.  NULL cob_class OBJECTs are useful to pass around
  69.       when large amounts of data need to be passed from program to
  70.       program -- and in particular, when they need to be passed in an
  71.       asynchronous, resource-tracked manner.  A zero is a legal size for
  72.       the OBJECT (the longword after the CoreObject structure), and signals
  73.       a program's wish for DropObject() NOT to free the OBJECT when the
  74.       usecount falls to zero.  see: 'struct ClasslessObject' in
  75.       include:shadow/core.h]
  76.  
  77.  
  78.    A cob_class is a special kind of OBJECT.  It is guaranteed to contain
  79.    a Meta structure [include:shadow/coreMeta.h], which is a structure that
  80.    contains important method parsing and attribute parsing information,
  81.    AS WELL AS all the information contained in the CoreObject structure.
  82.  
  83.  
  84. METAS:
  85.  
  86.    This leads us to one of the most confusing elements of SHADOW --
  87.    if we label all cob_classes as "Classes", what is the cob_class of a
  88.    Class?
  89.  
  90.    Imagine a row of identical apartments in an apartment complex. If
  91.    we model these apartments under an object-oriented paradigm, the
  92.    apartments are instances (or OBJECTs) of a particular apartment-class.
  93.    The apartment-class serves as a blueprint for each of the apartments,
  94.    and, indeed, it is compelling to refer to the apartment blueprints
  95.    AS the class of the apartments.
  96.  
  97.    These blueprints, however, are also instances (or OBJECTs) of a
  98.    blueprint-class.  The blueprint-class is itself described in numerous
  99.    architectural books.  But architectural books are instances
  100.    (or OBJECTs) of a book-class.  This seemingly infinite series of
  101.    statements must terminate somewhere, and in real life it usually
  102.    terminates at some fuzzy boundary of understanding.  For example, while
  103.    most people would readily agree that an apartment must have a
  104.    blueprint, they would also have a great deal of trouble adequately
  105.    describing just what a blueprint contains.
  106.  
  107.    Unfortunately, computers are stupid and lack the ability to deal with
  108.    this kind of "fuzzy understanding."
  109.  
  110.    Fortunately, the reality is that this type of recursion always
  111.    terminates.  A "book" is described in a "dictionary" and a "dictionary"
  112.    is described in itself.  In short, we end in a self-referencing
  113.    recursion -- something is described by itself.
  114.  
  115.    Under SHADOW, the responsibility of parsing attribute requests and
  116.    method requests for a Class (or any cob_class, for that matter) is
  117.    the domain of a Meta.  A Meta is the "something" in SHADOW which
  118.    refers to itself.  More concretely, SHADOW's Metas are OBJECTs
  119.    whose cob_class points back to itself.
  120.  
  121.    A Meta contains the same type of information as a Class, excepting
  122.    that the OBJECT's cob_class points back to itself. This self-referencing
  123.    implies that all methods and attribute requests [ie: DoShadow(),
  124.    FindAttribute(), etc.) for Metas are handled by the Meta itself.  This
  125.    also implies that a Meta is an instance of itself.
  126.  
  127.    However, paradoxically, the instances of Metas are classes; or, less
  128.    ambiguously, the instances of Metas are OBJECTs which can legally
  129.    reside in the cob_class field of other OBJECTs.  This implies,
  130.    correctly, that a Meta is just another kind of cob_class....
  131.  
  132.    Metas exist for one main reason:  METH_CREATE -- or, rather, the
  133.    flexibility in creating new Metas which define new ways of creating
  134.    object instances.  For instance, the ability to create Metas gives
  135.    you, the programmer, the ability to create Classes that create
  136.    their instance OBJECTs via a calloc() call, instead of an AllocMem()
  137.    call.
  138.  
  139.    All OBJECTs are created by sending an OOP METH_CREATE "message" to the
  140.    associated cob_class of the OBJECT you want created.  Because all
  141.    methods of all objects are really handled by the cob_class of the
  142.    OBJECT, sending a "message" to a cob_class implies that the method
  143.    request is really "handled" by the cob_class' Meta.  Hence, the only
  144.    way to change a program's "object creation" call is to "subclass" a
  145.    Meta, creating a new Meta and rebinding the METH_CREATE method to
  146.    your own code.  [see: Figure.SLM.1]
  147.  
  148.    If this has confused you, you may want to refer back to Introduction.doc
  149.    which also contains information about the distinctions between Metas,
  150.    cob_classes, OBJECTs, etc.  It is important to understand the nuances
  151.    of Metas if you are to read this appendix in its entirety.  If, instead,
  152.    you are merely trying to reference a particular method in a class
  153.    like PROCESS_CLASS, then Metas are not important to you.
  154.  
  155.  
  156. OF SELECTORS, METHODS, and OOP MESSAGES:
  157.  
  158.    The discussion two paragraphs above introduces the OOP term "message"
  159.    into a programming model where "message" is already used to refer to
  160.    passing data from task to task, or passing data across machines.
  161.  
  162.    As page 293 of the RKM:Libraries points out:
  163.  
  164.       "The term 'message' used in object oriented terminology can be [a]
  165.        little confusing to the Amiga programmer because the Boopsi
  166.        message has nothing to do with an Exec message."
  167.  
  168.    The usage is similarly confusing under SHADOW.  Object-oriented
  169.    terminology uses the word "message" as a means of selecting which
  170.    method (or function) to execute to complete the method invocation
  171.    request (DoShadow(), DoShadowAsync(), PreParseShadow(), etc.).
  172.  
  173.    From now on, the less ambiguous terms "selector", "method", and
  174.    "invoke" will be used to describe the process of requesting and
  175.    servicing OOP "messages".  The term selector will refer to the OOP
  176.    term "message".  It is hoped that the terms "method" and "invoke" are
  177.    similarly easily understood.  We can, therefore, now say that a
  178.    programmer requests a method (a function) by passing a selector
  179.    (METH_CREATE, METH_PROC_ASSOCIATE, etc.) to the correct invoking macro
  180.    or library function (CallSuper(), DoShadow(), DoShadowInProcess(),
  181.    DSM(), etc.).  These terms are, hopefully, less ambiguous.
  182.  
  183.  
  184. SELECTORS:
  185.  
  186.    Under SHADOW, selectors are implemented as pointers to strings.  This
  187.    allows for large, unambiguous name-spaces, and with a few
  188.    straight-forward naming conventions, eliminates the need to surpervise
  189.    the creation of third party selectors.  SHADOW goes to a few lengths
  190.    to ensure that these strings have as little overhead on method
  191.    invocations as possible through the use of buffering method lookups,
  192.    and an implementation of a "strings" table which allows each string
  193.    that is used as a method-selector (or an attribute, class, etc.) to be
  194.    given a unique 32bit address.
  195.  
  196.    Thus, if a selector is not found in the buffered lookup table (ie: the
  197.    method wasn't recently invoked), the selector is found in the hashed
  198.    array of system strings, and the 32bit returned value is used to
  199.    radix search through the MethodTable of the cob_class.
  200.  
  201.  
  202. ATTRIBUTES:
  203.  
  204.    Attributes are also "named" using strings.  Attributes contain the
  205.    definition of the variables that are stored in an object.  Each
  206.    named attribute can refer to an entire C-structure of variables,
  207.    allowing for the usual object-oriented separation of each subclass'
  208.    attributes from its associated superclass'.  However, it is entirely
  209.    possible for a superclass to search for a subclass' set of variables
  210.    (as attributes, like methods, are bound at run-time, so no compilation
  211.    check can be done, and run-time checking would be prohibitive).  Care
  212.    on the part of the programmer must be taken that either superclasses
  213.    don't know about their subclass' attributes, or aren't effected by
  214.    their absence or existence.  In other words, for code such as:
  215.  
  216.       SuperClassMethod(METHOD_ARGS, other_args)
  217.       {
  218.          struct MySubClassVars mscv = FindAttribute(object, ATTR_SUB_VARS);
  219.  
  220.          .
  221.          .
  222.          .
  223.       }
  224.  
  225.    ...you must check "mscv" against NULL, and take the appropriate actions.
  226.    In most cases, however, you should avoid such behaviour.
  227.  
  228.  
  229. CLUSTERS:
  230.  
  231.    In addition to Classes, and as an example of "subclassing" Metas,
  232.    SHADOW defines Clusters as the cob_class of COMPOSITEs.  A
  233.    COMPOSITE is sort of like a bag of OBJECTs.  When the COMPOSITE is
  234.    fully initialized (see: METH_INIT), it contains a number of OBJECTs
  235.    stored in a binary tree.  The attribute of this binary tree is
  236.    represented as ATTR_BAG.  Therefore, you can get a pointer to the
  237.    binary tree (which is what y0u need to pass to the various binary tree
  238.    manipulation functions) by calling:
  239.  
  240.       AVLTree *bt;
  241.  
  242.       bt = (AVLTree *)FindAttribute(my_compositeObject, ATTR_BAG);
  243.  
  244.  
  245.    Or you can merely use the structure 'struct CoreComposite' and
  246.    de-reference directly off of that [include:shadow/coreRoot.h].
  247.  
  248.    Once the COMPOSITE is initialized, you may add or remove as many
  249.    objects as you like to/from the ATTR_BAG binary tree.  Caution: if you
  250.    remove an object, please remember to send the removed object a
  251.    METH_REMOVE method so that it can be removed from its cob_class'
  252.    instance tree as well.
  253.  
  254.  
  255. INHERITENCE:
  256.  
  257.    Methods are inherited from an object's cob_class' superclass, as are
  258.    attributes.  Inheritence, subclassing, and superclasses are all terms
  259.    that should be familiar to you either from previous object-oriented
  260.    programming, or from your perusal of my Glossary.doc and the
  261.    RKM:Libraries 3rd edition BOOPSI discussions.  Like Appendix B
  262.    in RKM:Libraries, this document describes each class in turn,
  263.    describing the new methods, the modified methods, the new attributes,
  264.    the superclass, and the include files that are associated with each
  265.    separate class.
  266.  
  267.    Each class inherits methods and attributes from its superclass by
  268.    default.  Therefore we will talk about classes in the order in which
  269.    they appear in the inheritence hierarchy.  The hierarchy is as follows:
  270.  
  271.                                  MetaClass
  272.                                      |
  273.                                      |
  274.                                 MetaCluster
  275.  
  276.  
  277.  
  278.  
  279.  
  280.                                  RootClass
  281.                         ________/    |    \__________
  282.                        |             |               |
  283.                   DirectorClass  PatcherClass  ProcessClass
  284.  
  285.  
  286.  
  287.  
  288.                                 RootCluster
  289.  
  290.  
  291. CLASS OVERVIEW:
  292.  
  293.    MetaClass and MetaCluster are the meta descriptions for Classes and
  294.    Clusters.  These are rarely used directly by the end programmer.
  295.    They are used indirectly for such things as creating instances,
  296.    classes, and subclasses of themselves.
  297.  
  298.    RootClass and RootCluster are the roots of the Class and Cluster
  299.    inheritence hiearchies  They do things like store the object into the
  300.    class' ATTR_INSTANCETREE (a watched binary tree), and they define
  301.    clusters as starting with an ATTR_BAG.  Again, these are rarely
  302.    directly used, they are more often used merely as classes to subclass.
  303.  
  304.    DirectorClass is the class for director objects, usually referred to as
  305.    watchers.  SHADOW defines a type of variable called WatchedVariables.
  306.    Director objects are the objects responsible for actually watching
  307.    these WatchedVariables.  They provide Notification methods, and also
  308.    support the ability to watch more than one variable at a time via the
  309.    ESTABLISH/TERMINATE method protocol.  Browser uses Director objects
  310.    (or watchers) in three separate ways.
  311.  
  312.    Browser uses watchers to watch the instance tree of every opened
  313.    Meta/Class/Instance listing so that it can keep the listings as current
  314.    as possible.  It also uses watchers to keep the "number of patches"
  315.    in the Method display windows current.  In addition, browser uses
  316.    something known as a "class watcher" to watch all of the instances of
  317.    all of the subclasses of a certain class -- in this case, it watches
  318.    the ATTR_GUICHILDREN of all windows and gets notification every time
  319.    a window has a child (usually a gadget) added or removed from the
  320.    ATTR_GUICHILDREN tree.
  321.  
  322.  
  323.    PatcherClass is the class for method patch objects.  Every method in
  324.    SHADOW can be patched -- this is SetFunction() done right!  Method
  325.    patches for a class are located in a watched list referred to as
  326.    ATTR_PATCHEDVERBS.  Patches have a priority (higher priority patches
  327.    get invoked before lower priority patches -- regular methods are default
  328.    priority zero), can dynamically prevent subsequent patches of lower
  329.    priority from being invoked, and may only patch a single verb at a time,
  330.    unlike watchers.  Please Note!:  it is impossible to patch the DESTROY
  331.    method -- see RemoveAllPatches() for more details.
  332.  
  333.    Patches are useful when attempting to change the behaviour of some
  334.    non-native application, some feature of some class you don't like,
  335.    or for distributing bug fixes.
  336.  
  337.  
  338.    ProcessClass (more accurately referred to as ThreadClass, because of
  339.    the way AmigaDOS treats Tasks/Processes) is the class for process
  340.    objects.  They attach themselves to your task->tc_UserData field,
  341.    SO DON'T MESS WITH THAT FIELD!  Process objects keep track of IPC
  342.    ports, the parent task pointer (0 if no parent), the message for use
  343.    during synchronous communications, etc.   Each program that intends
  344.    to invoke methods, either actively via DoShadow() or DSM(), or
  345.    passively via DropObject() or possibly even via callbacks in the
  346.    FindAttribute() code, should generally call InitOOProgram().
  347.  
  348.    Unfortunately, this makes subclassing ProcessClass for your own
  349.    program's process more or less pointless because InitOOProgram()
  350.    associates a default process to your already running program.
  351.    Fortunately, because METH_SUB is actually a callback method, it is safe
  352.    to create a subclass of Process Class and then send that class a
  353.    METH_CREATE followed by a METH_PROC_ASSOCIATE as documented later in
  354.    this file.  The attribute ATTR_SHADOWPROCESS -must- be located eight
  355.    bytes from the start of the object, so please don't define your own
  356.    private process-class unless it is a subclass of ProcessClass.
  357.    The exact contents of ATTR_SHADOWPROCESS are subject to change, and in
  358.    fact HAVE changed from version 4 to version 5!
  359.  
  360.    Processes have become generally more useful in version 5 because of
  361.    the much cleaner startup conventions, and the plethora of new
  362.    method invocation possibilities.  ASLClass, for instance,
  363.    -automatically- starts up a new process each time a new AslObject
  364.    would block the main gui process.
  365.  
  366.  
  367. METHOD CALLING CONVENTIONS
  368.  
  369.    All methods are invoked by DSM() with at least four parameters.  The
  370.    first is a pointer to an IPCMessage structure.  If this parameter is
  371.    non-NULL, it means that the method was invoked with an asynchronous
  372.    method, and the passed IPCMessage is the message which was sent to the
  373.    task.  The name of this parameter is 'msg'.
  374.  
  375.    The second parameter is the object that the method was invoked on.
  376.    However, the term 'object' would be ambiguous, as the instance that
  377.    the method was invoked on may well be a class-object or a meta-object.
  378.    Nevertheless, in the code, the parameter is named 'object'.  In other
  379.    object-oriented languages, this is often defined to be 'self' or 'this'.
  380.    If you prefer this notation, the definition of METHOD_ARGS can be found
  381.    in include:shadow/misc.h.  Feel free to change them for your own
  382.    convenience.
  383.  
  384.    The third parameter is the class pointer, which is the pointer to
  385.    the class for which the method is defined (under the hierarchy of the
  386.    object->cob_class, of course).  The parameter's name in the code is
  387.    'class'.
  388.  
  389.    The last default parameter is the selector itself.  This is guaranteed
  390.    to be a pointer to the system string which stores the name of the
  391.    method.  This parameter is named 'MethodID'.
  392.  
  393.    All four of these parameters can be found in the METHOD_ARGS #define in
  394.    the include file: shadow/misc.h.
  395.  
  396.  
  397. SYSTEM CLASS REFERENCE
  398.  
  399.    Class:         META_CLASS
  400.    Superclass:    -none-
  401.    Include File:  <shadow/coreMeta.h>
  402.  
  403.    This is the universal meta for all other metas.
  404.  
  405.       Attributes:
  406.          ATTR_CORE         -- The minimal class variables, including the
  407.                                attribute and method table pointers.
  408.                               Implemented as struct Meta and typedef'd
  409.                                as META.
  410.                               Access to this attribute is priviledged,
  411.                                and usually unnecessary anyway.
  412.  
  413.          ATTR_PATCHEDVERBS -- Watched list of method patches.
  414.                               Access to this attribute is managed through
  415.                                the method patching class.
  416.  
  417.          ATTR_INSTANCETREE -- Watched binary tree of meta's instances.
  418.                                Metas are kept on a special watched binary
  419.                                tree located in ShadowBase->sb_metaTree.
  420.                                Classes (as instances of MetaClass) are
  421.                                kept on this INSTANCETREE.  Note that even
  422.                                though Metas are, strictly, instances of
  423.                                themselves, they do not exist on their
  424.                                own INSTANCETREE.
  425.                               The Class Browser uses the watched aspect
  426.                                of this binary tree and gets notification
  427.                                whenever any new Class is created and
  428.                                added to this tree.  Instances are added
  429.                                to the tree when the METH_INIT is sent to
  430.                                them.
  431.  
  432.       New Methods:
  433.  
  434.          METH_CREATE
  435.             run as:
  436.                function in invoker's process.
  437.  
  438.             arguments:
  439.                none.
  440.  
  441.                NOTE: this function may NOT be invoked asynchronously!
  442.                Returns a pointer to an uninitialized object.  Sets an
  443.                 error in the current process error field if it can't
  444.                 allocate an object-class "CANNOT_ALLOCATE_OBJECT"
  445.                 [see include:shadow/misc.h]
  446.  
  447.             purpose:
  448.                CreateInstance() uses this method to create a new instance
  449.                of a class.  Programs which prefer to invoke the method
  450.                directly can as well, however there is no known
  451.                reason why programs would wish to do so, except,
  452.                perhaps, for testing purposes.
  453.  
  454.             restrictions:
  455.                none
  456.  
  457.             function:
  458.                Allocates an instance of a particular class.  IE:this is a
  459.                method which is sent to a Class, not its instances.
  460.                It creates an object, fills in the class field and any
  461.                default attribute values as specified in the class attribute
  462.                table, and returns the allocated object.
  463.  
  464.                Note that this object CANNOT have anything done to it UNTIL
  465.                it is sent a METH_INIT.  Among other things, the useCount is
  466.                zero.  DSM() correctly fails and frees the object if invoking
  467.                the METH_INIT fails for any reason (like the destination
  468.                process has it's port closed, or memory is running low).
  469.  
  470.                Memory is allocated :: (MEMF_PUBLIC | MEMF_CLEAR)
  471.  
  472.             example:
  473.                .
  474.                .
  475.                .
  476.                /*
  477.                 * Allocation example code.
  478.                 */
  479.                procClass = FindShadowClass(PROCESS_CLASS);
  480.                procObject = DoShadow(procClass,
  481.                                      NULL,
  482.                                      METH_CREATE,
  483.                                      METHOD_END);
  484.                procObject = DoShadow(procObject,
  485.                                      NULL,
  486.                                      METH_INIT,
  487.                                      METHOD_END);
  488.                DropObject(procClass);
  489.                .
  490.                .
  491.                .
  492.                /*
  493.                 * Cleanup code.
  494.                 */
  495.                RemovObject(procObject);
  496.  
  497.  
  498.          METH_DESTROY
  499.             run as:
  500.                function in invoker's process.
  501.  
  502.             arguments:
  503.                none
  504.  
  505.             purpose:
  506.                METH_DESTROY frees an object.
  507.                When DropObject() notices that the usecount has fallen to
  508.                zero, it invokes the METH_DESTROY method on the object.
  509.  
  510.             restrictions:
  511.                You should never invoke this method yourself!
  512.                This method is always invoked by DropObject()!
  513.  
  514.             function:
  515.                Invalidates the cache for any cache lines with the class
  516.                being destroyed.  See InvalidateCache() for details.
  517.                Frees any leftover watchers on the class
  518.                [FreeObjectWatchers()], destroys the method and attribute
  519.                tables, drops the class name and superclass references,
  520.                frees the object, drops its class, and handles the case of
  521.                transferring the pointer from the 'msg' field to
  522.                non-existence, just in case this method is invoked
  523.                asynchronously (which should NEVER happen).  This is the
  524.                second half of the two-level resource tracking.  This
  525.                function is invoked by DropObject() when the useCount of
  526.                the object drops to zero, implying no one has a pointer to
  527.                the object.  As evidenced by the FreeObjectWatchers() call,
  528.                this may not be entirely TRUE, but watchers are a special
  529.                case.
  530.                Also calls RemoveAllPatches().
  531.  
  532.             example:
  533.                /*
  534.                 * Assuming the assert works, the DropObject()
  535.                 * invokes the METH_DESTROY method.
  536.                 */
  537.                assert(CheckUseCount(object) == 1);
  538.                DropObject(object);  /*
  539.                                      * This calls the METH_DESTROY method.
  540.                                      * This is the only legal way to have
  541.                                      *  the METH_DESTROY method called.
  542.                                      */
  543.                /*
  544.                 * NOTE!!!!  In practice, you do not assert() usecounts
  545.                 *  like this anymore than you would assert any other kind
  546.                 *  of usecount.  In real life, the DropObject() calls
  547.                 *  the object's METH_DESTROY method whenever the usecount
  548.                 *  falls to zero.  If the usecount is one before entering
  549.                 *  DropObject(), then the usecount obviously falls to
  550.                 *  zero, and the METH_DESTROY is then called.  The assert
  551.                 *  is there only to differentiate the many calls you can
  552.                 *  make to DropObject() that do NOT invoke the
  553.                 *  METH_DESTROY method from this case, which does.
  554.                 */
  555.  
  556.  
  557.          METH_INIT
  558.             run as:
  559.                function in invoker's process.
  560.             arguments:
  561.                JSTR -- name of the class to create
  562.                JOBJ -- optional superclass of the class to create.
  563.                TAGL -- NULL terminated array of struct AttributeTag.  NULL
  564.                         is also valid.
  565.                TAGL -- NULL terminated array of struct MethodTag.  NULL is
  566.                         also valid.
  567.  
  568.                Returns a pointer to the initialized object.  NULL on
  569.                failure.  Object destroyed on failure....
  570.  
  571.             purpose:
  572.                Initializes the class or meta by filling in the superclass,
  573.                methods, and attributes of the new class or meta.
  574.                Call this method directly ONLY when you are creating
  575.                your own root of a "class" or meta hierarchy.  Otherwise,
  576.                the METH_SUB is far more useful.
  577.  
  578.             restrictions:
  579.                Call this directly only for "root"s of cob_class
  580.                hierarchies.
  581.  
  582.             function:
  583.                Methods that are defined in metas have a rather disturbing
  584.                property.  Recall that metas are responsible for handling
  585.                their own methods AS WELL AS the methods of their
  586.                instances.
  587.  
  588.                However, the normal path of execution for a METH_INIT is to
  589.                initialize all variables of the object being defined.  As
  590.                noted in the "purpose" field above, this includes the
  591.                method and attribute arrays of the class/meta being
  592.                defined.  It is clearly impossible, therefore, for a meta
  593.                to completely handle its own METH_INIT.  What gives?
  594.  
  595.                Well, creation of "root" metas (that constitutes the
  596.                META_CLASS -- META_CLUSTER is a subclass of META_CLASS)
  597.                requires a call to the library function CreateMeta().
  598.                CreateMeta() actually fills in the meta's method and
  599.                attribute fields, and then invokes the METH_INIT on the
  600.                (half-filled) meta.
  601.  
  602.                Therefore, it is up to this method call to distinguish
  603.                the distinction between half-filled metas, and completely
  604.                empty classes.  This is accomplished by comparing
  605.                object->cob_class to object.  Recall that ALL metas are
  606.                self-referencing by nature -- self-referencing in that
  607.                the object->cob_class field points back to object.  So,
  608.                the METH_INIT distinguishes between the cases and takes
  609.                the appropriate actions as listed below:
  610.  
  611.                   If the method is being invoked on a meta,
  612.                   the superclass, attribute array, instance size, and
  613.                   method array are left alone.
  614.                   Otherwise, if the method is being invoked on a class
  615.                   that is not a meta, this function fills in the
  616.                   superclass, the attribute table, the instance size,
  617.                   and the method table.
  618.  
  619.                In either case, it fills in the class name, binds all the
  620.                appropriate class watchers for its attributes  [Ed:
  621.                watched variables have both a list of watchers, and a
  622.                pointer to a second list of watcher.  SHADOW uses this
  623.                second pointer to point to a list of watchers managed by
  624.                the class.  Under MetaClass and MetaCluster, these 'class'
  625.                watchers are copied into all subclasses.  See
  626.                BindSuperWatchers() for more details], and adds the object
  627.                into its class' ATTR_INSTANCETREE.  In the case of a meta,
  628.                this would be Shadow->sb_metaTree.  It also calls
  629.                BindWatchers() on the object which binds the second
  630.                watch-list pointer of all watched variables to the class'
  631.                attributes' SList.  See the struct Attribute definition and
  632.                the AutoDocs for BindWatchers().
  633.  
  634.             example:
  635.  
  636.                /*
  637.                 * Retrieve the meta in which to create the base class.
  638.                 */
  639.                metaclass = FindWatchedTreeStringNode(
  640.                               &ShadowBase->sb_metaTree,
  641.                               META_CLASS);
  642.                /*
  643.                 * Create the base class.
  644.                 *
  645.                 * myRootClustAttributes is a NULL terminated array
  646.                 *       of AttributeTag structures.
  647.                 * myRootClustMethods is a NULL terminated array of
  648.                 *       MethodTag structures.
  649.                 */
  650.                myroot = CreateInstance(metaclass, NULL,
  651.                                                   NULL,
  652.                                                   MY_ROOT_CLASS,
  653.                                                   NULL,
  654.                                                   myRootClassAttributes,
  655.                                                   myRootClassMethods,
  656.                                                   METHOD_END);
  657.                DropObject(metaclass);  /*
  658.                                         * Don't need the metaclass
  659.                                         * pointer anymore.
  660.                                         */
  661.                .
  662.                .
  663.                .
  664.  
  665.                /*
  666.                 * Cleanup!
  667.                 */
  668.                RemoveObject(myroot);
  669.                .
  670.                .
  671.                .
  672.  
  673.                /*
  674.                 * Creation of MetaClass:
  675.                 */
  676.                struct InitMeta __far globalIM = {
  677.                                        NULL,
  678.                                        NULL,
  679.                                        NULL,    /* METH_INIT is default */
  680.                                        META_CLASS, /* meta name */
  681.                                        NULL,       /* no super. */
  682.                                        metaClassAttrs,
  683.                                        metaClassMethods,
  684.                                        METHOD_END,
  685.                                     };
  686.                metaclass = CreateMeta(&globalIM);
  687.                .
  688.                .
  689.                .
  690.  
  691.                /*
  692.                 * Cleanup!
  693.                 */
  694.                RemoveObject(metaclass);      /* this meta
  695.                                               * no longer needed.
  696.                                               */
  697.  
  698.  
  699.          METH_REMOVE
  700.             run as:
  701.                function in invoker's process.
  702.             arguments:
  703.                none
  704.  
  705.             purpose:
  706.                Removes a class from the system list, initiates the first
  707.                pass of the two-level resource tracking algorithm.
  708.                Call this method when you are done with a class and want
  709.                it to be removed from being referenced by the system.  The
  710.                class will continue to exist until all references to it are
  711.                gone -- that implies that all instances of the class are
  712.                gone as each instance of a class is pointed to by the
  713.                instance's cob_class field.
  714.  
  715.                RemoveObject() calls the METH_REMOVE function to Remove
  716.                classes and objects.
  717.  
  718.             restrictions:
  719.                After calling this method, you may not have circular
  720.                references to this item, nor may you cause such
  721.                circular references to come into existence.
  722.  
  723.             function:
  724.                Frees all class watchers associated with this class.  See
  725.                FreeClassWatchers() for further details.  Removes the
  726.                instance (in this method, the instance is a Class) from its
  727.                class' ATTR_INSTANCETREE.  If this is a Meta being removed,
  728.                the Meta is removed from ShadowBase->sb_metaTree instead.
  729.                This is the first of the two-level resource tracking done
  730.                on objects.  In addition, removal from this tree implies
  731.                that the system can no longer find your class/meta,
  732.                effectively removing it from the system.  It is not
  733.                destroyed, however, until no one has a pointer to it
  734.                (assuming they have used UseObject() and DropObject()
  735.                appropriately.  All self-references, either direct or
  736.                indirect, should be eliminated in this method.
  737.  
  738.             example:
  739.                /*
  740.                 * Cleanup code.
  741.                 */
  742.                RemoveObject(FindShadowClass(MYDOS_CLASS));
  743.                            /*
  744.                             * FindShadowClass() returns a used class
  745.                             *  pointer to MYDOS_CLASS.
  746.                             * RemoveObject() then invokes the METH_REMOVE
  747.                             *  method, and DropObject()s the passed class.
  748.                             */
  749.  
  750.                .
  751.                .
  752.                .
  753.  
  754.                /*
  755.                 * More example Cleanup Code.
  756.                 * Assumes DosClass is already a valid pointer to your
  757.                 *  class.
  758.                 */
  759.                RemoveObject(DosClass);
  760.                            /*
  761.                             * RemoveObject() invokes the METH_REMOVE on
  762.                             *  DosClass and DropObject()s the passed
  763.                             *  class.
  764.                             * DosClass is no longer a valid pointer
  765.                             *  to the DosClass object anymore.  Indeed,
  766.                             *  the DosClass itself may very well have
  767.                             *  disappeared.
  768.                             */
  769.                .
  770.                .
  771.                .
  772.  
  773.  
  774.          METH_SUB
  775.             run as:
  776.                function in invoker's process.
  777.             arguments:
  778.                JSTR -- name of the class to create
  779.                JOBJ -- optional superclass of the class to create.  This
  780.                         method is, however, sent to the class that is to
  781.                         be subclassed, so if this parameter is NULL, it
  782.                         defaults to the object which the method was sent to.
  783.                TAGL -- NULL terminated array of struct AttributeTag.  NULL
  784.                         is also valid.
  785.                TAGL -- NULL terminated array of struct MethodTag.  NULL is
  786.                         also valid.
  787.  
  788.             purpose:
  789.                Creates a new subclass.
  790.                CreateSubClass() calls this method.
  791.                You should probably use CreateSubClass(), but it takes
  792.                parameters exactly equivalent to what's shown here, so
  793.                it's good to reference this method when you need to
  794.                know the arguments to pass to CreateSubClass().
  795.  
  796.                This is basically equivalent to a METH_CREATE followed
  797.                by a METH_INIT where the object you invoke the
  798.                METH_SUB on ends up being the superclass sent into the
  799.                METH_INIT.
  800.  
  801.             restrictions:
  802.                none
  803.  
  804.             function:
  805.                Note the description of the complications of sending
  806.                METH_INITs to metas in the METH_INIT description
  807.                above.  Note that the METH_SUB is really just a
  808.                convenient wrapper around the METH_CREATE and the
  809.                METH_INIT methods.
  810.  
  811.                If this method is invoked on a meta (that is, if object ==
  812.                object->cob_class), then instead of invoking METH_CREATE
  813.                and METH_INIT, this function MUST call CreateMeta() in
  814.                order to setup the methds, attributes, etc. of the meta.
  815.                In this case, the CreateMeta() is called with the InitMeta
  816.                structure set as the parameter list passed into METH_SUB
  817.                (minus the 'msg' pointer).  CreateMeta() then calls the
  818.                METH_INIT method as described in the CreateMeta() autodoc.
  819.                The return value is equivalent to whatever CreateMeta
  820.                returns.
  821.  
  822.                Otherwise, if the method isn't invoked on a meta, this
  823.                method instantiates a meta (creating a Class Object)
  824.                and sends a METH_INIT to it, returning whatever the INIT
  825.                method returns.
  826.  
  827.             examples:
  828.                /*
  829.                 * Creates a new class as a subclass of rootclass.
  830.                 */
  831.                newClass = CreateSubClass(NULL, ROOT_CLASS,
  832.                                                META_CLASS,
  833.                                                MYDOS_CLASS,
  834.                                                NULL,
  835.                                                my_new_attributes,
  836.                                                my_new_methods,
  837.                                                METHOD_END);
  838.  
  839.                /*
  840.                 * Creates a new class as a subclass of some private class.
  841.                 */
  842.                newClass2 = CreateSubClass(oldClass, NULL,
  843.                                                     NULL,
  844.                                                     MY_NEW_CLASS,
  845.                                                     NULL,
  846.                                                     my_new_attributes,
  847.                                                     my_new_methods,
  848.                                                     METHOD_END);
  849.  
  850.                /*
  851.                 * Creates a new meta as a "sub-meta" of metaclass.
  852.                 */
  853.                newMeta = CreateSubClass(NULL, META_CLASS,
  854.                                               NULL,
  855.                                               MY_META,
  856.                                               NULL,
  857.                                               my_new_attributes,
  858.                                               my_new_methods,
  859.                                               METHOD_END);
  860.  
  861.                /*
  862.                 * Note: CreateSubClass is a stub routine that calls
  863.                 *       METH_SUB.
  864.                 *
  865.                 * Note2: Don't forget to cleanup your allocations!
  866.                 */
  867.  
  868.          METH_SUPER
  869.             run as:
  870.                function in invoker's process.
  871.             arguments:
  872.                JSTR -- name of the class to create
  873.                JOBJ -- optional subclass of the class to override.  This
  874.                         method is, however, sent to the class that is to
  875.                         be "superClassed", so if this parameter is NULL, it
  876.                         defaults to the object which the method was sent to.
  877.                TAGL -- NULL terminated array of struct AttributeTag.  NULL
  878.                         is also valid.
  879.                TAGL -- NULL terminated array of struct MethodTag.  NULL is
  880.                         also valid.
  881.  
  882.             purpose:
  883.                Creates a new superclass for an existing class.
  884.                Thus, in effect, adding methods to an existing class tree.
  885.  
  886.             restrictions:
  887.                The new superClass must be created as a subclass of the
  888.                passed class' superclass [that is, the superclass of the
  889.                object (class) the method was invoked on].
  890.                The class must HAVE a superClass -- ie: you cannot
  891.                invoke this method on ROOT_* classes.
  892.                This new class may NOT add any new attributes.
  893.  
  894.             function:
  895.                The METH_SUB method is invoked on the passed class'
  896.                superclass.  The InsertSuperClass() function is
  897.                then called (this function flushes the method cache as
  898.                well!).
  899.  
  900.             examples:
  901.                /*
  902.                 * Creates a new superclass of a subclass.
  903.                 * Adds the methods specific in the my_new_method structure.
  904.                 */
  905.                procClass = FindShadowClass(PROCESS_CLASS, META_CLASS);
  906.                newClass = DoShadow(procClass, NULL, METH_SUPER,
  907.                                    MY_INTERMEDIATE_CLASS,
  908.                                                NULL,
  909.                                                my_new_attributes,
  910.                                                my_new_methods,
  911.                                                METHOD_END);
  912.                DropObject(procClass);
  913.  
  914.                .
  915.                .
  916.                .
  917.  
  918.                RemoveObject(newClass);
  919.  
  920.  
  921.  
  922.    Class:         META_CLUSTER
  923.    Superclass:    META_CLASS
  924.    Include File:  <shadow/coreMeta.h>
  925.  
  926.    This is an example of a "submeta".  It is really only intended
  927.    for demonstration purposes.  If you find a use for it yourself,
  928.    so much the better!
  929.  
  930.    MetaCluster is the blueprints for a class that creates a placeholder
  931.    for any number of other objects, and then creates those other
  932.    objects as well.  For example, you can create a workbench-icon
  933.    cluster which describes a workbench icon as a collection of a file
  934.    object and a graphic object.  When the cluster is instantiated
  935.    (creating a composite-object), the composite-object would have, as one
  936.    of its attributes, a binary tree with the newly instantiated file and
  937.    graphic objects in it.
  938.  
  939.       Attributes:
  940.          ATTR_CLASSTABLE   -- struct ClusterClassTable
  941.                               [see: include:shadow/coremeta.h].
  942.                               An array of classes that describes
  943.                               what objects the cluster should instantiate
  944.                               to put in the composite-object's binary tree.
  945.  
  946.       Modified Methods:
  947.          METH_DESTROY
  948.             run as:
  949.                function in invoker's process.
  950.  
  951.             arguments:
  952.                none
  953.  
  954.             purpose:
  955.                METH_DESTROY frees an object.
  956.                When DropObject() notices that the usecount has fallen to
  957.                zero, it invokes the METH_DESTROY method on the object.
  958.  
  959.             restrictions:
  960.                You should never invoke this method yourself!
  961.                This method is always invoked by DropObject()!
  962.  
  963.             function:
  964.                ATTR_CLASSTABLE is freed.
  965.                Method is then routed to the superclass.
  966.  
  967.             example:
  968.                See example under META_CLASS
  969.  
  970.  
  971.          METH_INIT
  972.             run as:
  973.                function in invoker's process.
  974.  
  975.             arguments:
  976.                JSTR -- name of the class to create
  977.                JOBJ -- optional superclass of the class to create.
  978.                TAGL -- NULL terminated array of struct AttributeTag.  NULL
  979.                         is also valid.
  980.                TAGL -- NULL terminated array of struct MethodTag.  NULL is
  981.                         also valid.
  982.                TAGL -- NULL terminated array of classes to fill in the
  983.                         ATTR_CLASSTABLE.  NULL is also valid.
  984.  
  985.                Returns a pointer to the initialized object.  NULL on
  986.                failure.  Object destroyed on failure....
  987.  
  988.             purpose:
  989.                Initializes the class or meta by filling in the superclass,
  990.                methods, and attributes of the new class or meta.
  991.                Call this method directly ONLY when you are creating
  992.                your own root of a "class" or meta hierarchy.  Otherwise,
  993.                the METH_SUB is far more useful.
  994.  
  995.             restrictions:
  996.                Call this directly only for "root"s of cob_class
  997.                hierarchies.
  998.  
  999.             function:
  1000.                Please refer to the note about meta creation in the
  1001.                METH_INIT method function description of META_CLASS.
  1002.  
  1003.                This method creates the array for the ATTR_CLASSTABLE
  1004.                attribute.
  1005.                The method is then routed to the superclass.
  1006.  
  1007.             example:
  1008.  
  1009.                /*
  1010.                 * Retrieve the meta in which to create the base class.
  1011.                 */
  1012.                metacluster = FindWatchedTreeStringNode(
  1013.                               &ShadowBase->sb_metaTree,
  1014.                               META_CLUSTER);
  1015.                /*
  1016.                 * Create the base cluster.
  1017.                 *
  1018.                 * myRootClustAttributes is a NULL terminated array
  1019.                 *       of AttributeTag structures.
  1020.                 * myRootClustMethods is a NULL terminated array of
  1021.                 *       MethodTag structures.
  1022.                 * myRootClustClasses is a NULL terminated array of
  1023.                 *       class -pointers-.
  1024.                 */
  1025.  
  1026.                myroot = CreateInstance(metacluster, NULL,
  1027.                                                     NULL,
  1028.                                                     MY_ROOT_CLUSTER,
  1029.                                                     NULL,
  1030.                                                     myRootClustAttributes,
  1031.                                                     myRootClustMethods,
  1032.                                                     myRootClustClasses,
  1033.                                                     METHOD_END);
  1034.                DropObject(metacluster);  /*
  1035.                                           * Don't need the metaclass
  1036.                                           * pointer anymore.
  1037.                                           */
  1038.                .
  1039.                .
  1040.                .
  1041.  
  1042.                /*
  1043.                 * Cleanup!
  1044.                 */
  1045.                RemoveObject(myroot);
  1046.                .
  1047.                .
  1048.                .
  1049.  
  1050.  
  1051.          METH_SUB
  1052.             run as:
  1053.                function in invoker's process.
  1054.  
  1055.             arguments:
  1056.                JSTR -- name of the class to create
  1057.                JOBJ -- optional superclass of the class to create.  This
  1058.                         method is, however, sent to the class that is to
  1059.                         be subclassed, so if this parameter is NULL, it
  1060.                         defaults to the object which the method was sent to.
  1061.                TAGL -- NULL terminated array of struct AttributeTag.  NULL
  1062.                         is also valid
  1063.                TAGL -- NULL terminated array of struct MethodTag.  NULL is
  1064.                         also valid.
  1065.                TAGL -- NULL terminated array of classes to fill in
  1066.                         ATTR_CLASSTABLE with.  NULL is also valid.
  1067.  
  1068.             purpose:
  1069.                Creates a new subclass.
  1070.                Adds an additional class_array parameter which is forwarded
  1071.                   to the METH_INIT method.
  1072.                See the desription of the METH_SUB method purpose in
  1073.                META_CLASS description above.
  1074.  
  1075.             restrictions:
  1076.                none
  1077.  
  1078.             function:
  1079.                Functionally identical to the METH_SUB in META_CLASS except
  1080.                that this method forwards the class_array parameter to
  1081.                the METH_INIT of META_CLUSTER.
  1082.  
  1083.             example:
  1084.                /*
  1085.                 * Creates a brand new meta for clusters.
  1086.                 */
  1087.                metaclass = FindWatchedTreeStringNode(
  1088.                               &ShadowBase->sb_metaTree,
  1089.                               META_CLASS);
  1090.                metaCluster = DoShadow(metaclass,
  1091.                                       NULL,
  1092.                                       METH_SUB,
  1093.                                       META_CLUSTER,
  1094.                                       metaclass,
  1095.                                       metaClusterAttrs,
  1096.                                       metaClusterMethods,
  1097.                                       METHOD_END);
  1098.                DropObject(metaclass);     /*
  1099.                                            * Uninterested in this pointer
  1100.                                            *  now.
  1101.                                            */
  1102.  
  1103.                /*
  1104.                 * Creates a new class as a subclass of rootcluster.
  1105.                 */
  1106.                newCluster = CreateSubClass(NULL, ROOT_CLUSTER,
  1107.                                                  META_CLUSTER,
  1108.                                                  MY_CLUSTER,
  1109.                                                  NULL,
  1110.                                                  my_new_attributes,
  1111.                                                  my_new_methods,
  1112.                                                  my_new_classes,
  1113.                                                  METHOD_END);
  1114.  
  1115.  
  1116.    Class:         ROOT_CLASS
  1117.    Superclass:    -none-
  1118.    Include File:  <shadow/coreRoot.h>
  1119.  
  1120.    This is the root cob_class for all META_CLASS classes.
  1121.  
  1122.       Attributes:
  1123.          none
  1124.  
  1125.       Methods:
  1126.          METH_DESTROY
  1127.             run as:
  1128.                function in invoker's process.
  1129.  
  1130.             arguments:
  1131.                none
  1132.  
  1133.             purpose:
  1134.                METH_DESTROY frees an object.
  1135.                When DropObject() notices that the usecount has fallen to
  1136.                zero, it invokes the METH_DESTROY method on the object.
  1137.  
  1138.             restrictions:
  1139.                You should never invoke this method yourself!
  1140.                This method is always invoked by DropObject()!
  1141.  
  1142.             function:
  1143.                Frees any leftover watchers on the object
  1144.                [FreeObjectWatchers()], frees the object, and drops its
  1145.                class.  Handles the case of transferring the pointer from
  1146.                the 'msg' field to non-existence, just in case this method
  1147.                is invoked asynchronously (which should NEVER happen).
  1148.                This is the second half of the two-level resource tracking.
  1149.                This function is invoked by DropObject() when the usecount
  1150.                of the object drops to zero, implying no one has a pointer
  1151.                to the object.  As evidenced by the FreeObjectWatchers()
  1152.                call, this may not be entirely TRUE, but watchers are a
  1153.                special case.
  1154.  
  1155.             example:
  1156.                See example under META_CLASS
  1157.  
  1158.  
  1159.          METH_INIT
  1160.             run as:
  1161.                function in invoker's process
  1162.  
  1163.             arguments:
  1164.                JSTR -- name of the object to create (optional).  If
  1165.                         specified, object stored on ATTR_INSTANCETREE is
  1166.                         sorted by the address of the string, rather than
  1167.                         the address of the object itself.
  1168.  
  1169.                Returns a pointer to the initialized object.  NULL on
  1170.                failure.
  1171.  
  1172.             purpose:
  1173.                Initializes the object and makes it a part of the
  1174.                system-shared resources.
  1175.                In reality, ROOT_CLASS exists to be subclassed.
  1176.  
  1177.             restrictions:
  1178.                none
  1179.  
  1180.             function:
  1181.                Adds object to ATTR_INSTANCETREE of its class, either sorted
  1182.                by the address of the passed string, or, if NULL string, by
  1183.                the object's own address.  Note that these are AVL trees,
  1184.                so the tree remains well-balanced, regardless of the ordering
  1185.                of allocated memory.
  1186.  
  1187.                Also calls BindWatchers() to bind all the watched attributes
  1188.                of the object's second List to the class attribute's watched
  1189.                list.  See BindWatchers() for more details.
  1190.  
  1191.             example:
  1192.                /*
  1193.                 * Create an instance of ROOT_CLASS
  1194.                 */
  1195.                rootObject = CreateInstance(NULL, ROOT_CLASS,
  1196.                                                  META_CLASS,
  1197.                                                  MY_OBJECT_NAME,
  1198.                                                  METHOD_END);
  1199.                .
  1200.                .
  1201.                .
  1202.  
  1203.                /*
  1204.                 * Cleanup!
  1205.                 * NOTE!!!  You must call the METH_REMOVE directly
  1206.                 *    with the name of the object or the removal will
  1207.                 *    not occur correctly (ie: not at all).
  1208.                 */
  1209.                DoShadow(rootObject, NULL, METH_REMOVE, MY_OBJECT_NAME,
  1210.                                                        METHOD_END);
  1211.  
  1212.                /*
  1213.                 * Note2: usually you keep the object name in the object's
  1214.                 *   instance as handled by some superclass.  It is highly
  1215.                 *   suggested that you put such names into the FIRST
  1216.                 *   attribute as the FIRST field for future compatibility
  1217.                 *   reasons.
  1218.                 */
  1219.                DropObject(rootObject);
  1220.  
  1221.  
  1222.          METH_REMOVE
  1223.             run as:
  1224.                function in invoker's process.
  1225.  
  1226.             arguments:
  1227.                JSTR -- optional string under which the object might have
  1228.                         been stored (in the ATTR_INSTANCETREE). Iif the
  1229.                         METH_INIT was invoked with a string as a
  1230.                         parameter, then the METH_REMOVE better be, or it
  1231.                         will fail to work properly.
  1232.  
  1233.             purpose:
  1234.                Removes an object from the class' ATTR_INSTANCETREE.
  1235.                Initiates the first pass of the two-level resource tracking
  1236.                algorithm.  Call this method when you are done with an
  1237.                object and want it to be removed from being referenced by
  1238.                the system.  The object will continue to exist until all
  1239.                references to it are gone.
  1240.  
  1241.                RemoveObject() calls the METH_REMOVE function to Remove
  1242.                classes and objects.
  1243.  
  1244.             restrictions:
  1245.                If you called the METH_INIT on this object with a non-NULL
  1246.                name-parameter, you MUST call the METH_REMOVE with this
  1247.                same name!
  1248.  
  1249.                After calling this method, you may not have circular
  1250.                references to this item, nor may you cause such
  1251.                circular references to come into existence.
  1252.  
  1253.             function:
  1254.                Removes the object from its class' ATTR_INSTANCETREE.
  1255.  
  1256.             example:
  1257.                see the METH_INIT method example for this class above.
  1258.  
  1259.  
  1260.    Class:         ROOT_CLUSTER
  1261.    Superclass:    -none-
  1262.    Include File:  <shadow/coreRoot.h>
  1263.  
  1264.    This is the root cob_class for all META_CLUSTER clusters.
  1265.  
  1266.       Attributes:
  1267.          ATTR_BAG -- binary tree which all objects are stored on.
  1268.                      NOT a watched binary tree!
  1269.  
  1270.       Modified Methods:
  1271.          METH_DESTROY
  1272.             run as:
  1273.                function in invoker's process.
  1274.  
  1275.             arguments:
  1276.                none
  1277.  
  1278.             purpose:
  1279.                METH_DESTROY frees an object.
  1280.                When DropObject() notices that the usecount has fallen to
  1281.                zero, it invokes the METH_DESTROY method on the object.
  1282.  
  1283.             restrictions:
  1284.                You should never invoke this method yourself!
  1285.                This method is always invoked by DropObject()!
  1286.  
  1287.             function:
  1288.                Removes all objects on the composite's ATTR_BAG and sends
  1289.                a METH_REMOVE to all of them.
  1290.                Method is then routed to the superclass.
  1291.  
  1292.             example:
  1293.                See example under META_CLASS
  1294.  
  1295.  
  1296.          METH_INIT
  1297.             run as:
  1298.                function in invoker's process
  1299.  
  1300.             arguments:
  1301.                JSTR -- name of the object to create (optional).  If
  1302.                         specified, object stored on ATTR_INSTANCETREE is
  1303.                         sorted by the address of the string, rather than
  1304.                         the address of the object itself.
  1305.  
  1306.                Returns a pointer to the initialized object.  NULL on
  1307.                failure.
  1308.  
  1309.             purpose:
  1310.                Initializes the object and makes it a part of the
  1311.                system-shared resources.
  1312.                In reality, ROOT_CLUSTER exists to be subclassed.
  1313.  
  1314.             restrictions:
  1315.                none
  1316.  
  1317.             function:
  1318.                METH_CREATEs and METH_INITs (without arguments) all
  1319.                objects whose classes are on the ATTR_CLASSTABLE of this
  1320.                composite's cluster.  Objects are stored on the ATTR_BAG's
  1321.                binary tree under the name of the class.
  1322.  
  1323.                Method continues in exactly the way that the METH_INIT
  1324.                method does in the ROOT_CLASS as described above.
  1325.  
  1326.             example:
  1327.                /*
  1328.                 * Create an instance of ROOT_CLUSTER
  1329.                 */
  1330.                rootObject = CreateInstance(NULL, ROOT_CLUSTER,
  1331.                                                  META_CLUSTER,
  1332.                                                  MY_OBJECT_NAME,
  1333.                                                  METHOD_END);
  1334.                .
  1335.                .
  1336.                .
  1337.  
  1338.                /*
  1339.                 * Cleanup!
  1340.                 * NOTE!!!  See notices in the METH_INIT example oF
  1341.                 * ROOT_CLASS above.
  1342.                 */
  1343.                DoShadow(rootObject, NULL, METH_REMOVE, MY_OBJECT_NAME,
  1344.                                                        METHOD_END);
  1345.                DropObject(rootObject);
  1346.  
  1347.  
  1348.          METH_REMOVE
  1349.             run as:
  1350.                function in invoker's process.
  1351.  
  1352.             arguments:
  1353.                JSTR -- optional string under which the object might have
  1354.                         been stored (in the ATTR_INSTANCETREE).  If the
  1355.                         METH_INIT was invoked with a string as a
  1356.                         parameter, then the METH_REMOVE better be, or it
  1357.                         will fail to work properly.
  1358.  
  1359.             purpose:
  1360.                Removes a composite from the cluster's ATTR_INSTANCETREE.
  1361.                Initiates the first pass of the two-level resource tracking
  1362.                algorithm.  Call this method when you are done with a
  1363.                composite and want it to be removed from being referenced by
  1364.                the system.  The composite will comtinue to exist until all
  1365.                references to it are gone.
  1366.  
  1367.                RemoveObject() calls the METH_REMOVE function to Remove
  1368.                all classes and objects.
  1369.  
  1370.             restrictions:
  1371.                If you called the METH_INIT on this composite with a
  1372.                non-NULL name-parameter, you MUST call the METH_REMOVE with
  1373.                this same name!
  1374.  
  1375.                After calling this method, you may not have circular
  1376.                references to this item, nor may you cause such
  1377.                circular references to come into existence.
  1378.  
  1379.             function:
  1380.                Removes the composite from its clster's ATTR_INSTANCETREE.
  1381.  
  1382.             example:
  1383.                see the METH_INIT method example for this cluster above.
  1384.  
  1385.  
  1386.    Class:         DIRECTOR_CLASS
  1387.    Superclass:    ROOT_CLASS
  1388.    Include File:  <shadow/watcher.h>
  1389.  
  1390.    The class that creates watchers to establish notification of changes
  1391.    to watched variables.
  1392.  
  1393.       Attributes:
  1394.          ATTR_MANAGER  -- struct ManagementNode
  1395.                            [see: include:shadow/watcher.h].
  1396.                            The place where useful information about the
  1397.                            director is stored.  For instance, information
  1398.                            managing the conditions under which
  1399.                            notification is sent, and to whom
  1400.                            it is sent.
  1401.          ATTR_DIRECTOR -- a WatchedList.  It is a list of all the
  1402.                            established connections that have been made;
  1403.                            in short, a list of all objects this Director
  1404.                            is watching.  Interestingly, you can get
  1405.                            notification of when the notification lists
  1406.                            change.  And, of course, you can even have a
  1407.                            class watcher watch everything at once!
  1408.  
  1409.       New Methods:
  1410.          METH_DIRECTOR_ESTABLISH
  1411.             run as:
  1412.                function in invoker's process.
  1413.  
  1414.             arguments:
  1415.                APTR -- the attribute-name of the object to watch, or a
  1416.                         pointer to the actual watchedVariable, if no
  1417.                         object is specified.  This implies that this
  1418.                         method CANNOT be safely invoked ASYNCronously.
  1419.                JOBJ -- the object in which the WatchedVariable is.  If
  1420.                         this parameter is NULL, the method assumes that
  1421.                         the APTR is a pointer to the WatchedVariable, and
  1422.                         not the name of the attribute.
  1423.                long -- priority of the watcher.
  1424.  
  1425.                Returns a handle to the connection.  You should either
  1426.                DropObject() the handle, or keep it to pass to the
  1427.                TERMINATE method, after which you should DropObject() it....
  1428.  
  1429.             purpose:
  1430.                Use this watcher to watch a particular watched variable.
  1431.                You should be prepared to service notifications of
  1432.                changes prior to invoking this method.
  1433.                All connections through a single "watcher" (or "director-
  1434.                object") will have notification sent to the ONE destination
  1435.                that that watcher had set up for it in its METH_INIT code.
  1436.  
  1437.             restrictions:
  1438.                May not be called asynchronously by DSM().  By default,
  1439.                this method is never run asynchronously.
  1440.  
  1441.             function:
  1442.                Establishes a connection and adds that connection to the
  1443.                ATTR_DIRECTOR list of connections.  Uses either
  1444.                AddClassWatcher() or AddWatcherNode(), depending on the
  1445.                type of Watcher this director-object is.  Please see the
  1446.                AutoDocs for more information on these functions.
  1447.  
  1448.                The Watcher may either be a SHADOW_OBJECT watcher or a
  1449.                SHADOW_CLASS watcher.  This is specified in the flags
  1450.                argument to the METH_INIT.
  1451.  
  1452.             examples:
  1453.                /*
  1454.                 * Create a director object.
  1455.                 * This is an example of a class watcher.
  1456.                 */
  1457.                GlobalDirector = CreateInstance(NULL,
  1458.                                                DIRECTOR_CLASS,
  1459.                                                META_CLASS,
  1460.                                                "WatchWindows",
  1461.                                                object,
  1462.                                                METH_DIRECTOR_NOTIFY,
  1463.                                                (W_INSERT_NODE | W_REMOVE) |
  1464.                                                (SHADOW_CLASS << 16) |
  1465.                                                W_FLAG_AUTOBREAK  |
  1466.                                                W_FLAG_AUTOREMOVE,
  1467.                                                METHOD_END);
  1468.  
  1469.                /*
  1470.                 * Establish the actual connection.  We don't care if
  1471.                 * GlobalDirector wasn't created successfully (ie: it is
  1472.                 * NULL), so that makes things easier.
  1473.                 *
  1474.                 * We are watching all the ATTR_GUICHILDREN of every instance
  1475.                 *  whose class is a subclass of WINDOW_CLASS
  1476.                 */
  1477.                windowClass = FindShadowClass(WINDOW_CLASS);
  1478.                DropObject(DoShadow(GlobalDirector,
  1479.                                    NULL,
  1480.                                    METH_DIRECTOR_ESTABLISH,
  1481.                                    ATTR_GUICHILDREN,
  1482.                                    windowClass,
  1483.                                    METHOD_END));
  1484.                DropObject(windowClass);
  1485.  
  1486.                .
  1487.                .
  1488.                .
  1489.                /*
  1490.                 * Cleanup!
  1491.                 *
  1492.                 * Note, because we INIT'd the director with the AUTO_BREAK,
  1493.                 * the director's connections are terminated when the
  1494.                 * METH_REMOVE is sent.
  1495.                 *
  1496.                 * Because we dropped the actual handle that the
  1497.                 *  ESTABLISH method returned, this is the only way we
  1498.                 *  can terminate the connection!
  1499.                 */
  1500.                RemoveObject(GlobalDirector);
  1501.  
  1502.                ----------
  1503.  
  1504.                /*
  1505.                 * This is an example of an object watcher.
  1506.                 */
  1507.                /*
  1508.                 * Create the director to watch the children of this object.
  1509.                 *
  1510.                 * When this object's children reaches zero, this object
  1511.                 *  should GO AWAY!
  1512.                 */
  1513.  
  1514.                director = CreateInstance(NULL,
  1515.                                          DIRECTOR_CLASS,
  1516.                                          META_CLASS,
  1517.                                          "WatchBlockedChildren",
  1518.                                          object,
  1519.                                          METH_DIRECTOR_NOTIFY,
  1520.                                          (W_INSERT_NODE | W_REMOVE) |
  1521.                                          (SHADOW_OBJECT << 16) |
  1522.                                          W_FLAG_AUTOBREAK |
  1523.                                          W_FLAG_AUTOREMOVE,
  1524.                                          METHOD_END);
  1525.                /*
  1526.                 * Establish the conection for the director.
  1527.                 */
  1528.                handle = DoShadow(director,
  1529.                                  NULL,
  1530.                                  METH_DIRECTOR_ESTABLISH,
  1531.                                  ATTR_GUICHILDREN,
  1532.                                  object,       /* object being watched */
  1533.                                  METHOD_END))
  1534.  
  1535.                .
  1536.                .
  1537.                .
  1538.  
  1539.                /*
  1540.                 * Cleanup!
  1541.                 */
  1542.                DoShadow(director, NULL, METH_DIRECTOR_TERMINATE, handle,
  1543.                         METHOD_END);
  1544.  
  1545.                /*
  1546.                 * Note: because this director was METH_INIT'd as
  1547.                 * W_FLAG_AUTOREMOVE, there is no reason to call
  1548.                 * RemoveObject() on the director as the METH_REMOVE
  1549.                 * has already been sent.  Recall, however, that
  1550.                 * RemoveObject() both sends the METH_REMOVE and
  1551.                 * drops the object from further use.  DropObject(),
  1552.                 * therefore, still needs to be called....
  1553.                 */
  1554.                DropObject(director);
  1555.  
  1556.          METH_DIRECTOR_TERMINATE
  1557.             run as:
  1558.                function in invoker's process.
  1559.  
  1560.             arguments:
  1561.                JOBJ -- either the handle as returned by the ESTABLISH
  1562.                         method, or a pointer to the object from which a
  1563.                         watcher should be removed.  The latter case
  1564.                         should be restricted to the
  1565.                         Free[Object|Class]Watchers() functions.  Mostly
  1566.                         because you are not guaranteed which handle of
  1567.                         the watcher is removed.  For instance, if one
  1568.                         watcher is watching more than one watched
  1569.                         variable of a single object, then invoking
  1570.                         TERMINATE with the object being watched may
  1571.                         release the watcher from any of those watched
  1572.                         variables.
  1573.                long -- flags dictating whether this is a handle, or
  1574.                         the object being watched, not specifying
  1575.                         this parameter defaults to the type 'handle'
  1576.                         (0), the other case is W_SORT -- value 1.
  1577.             purpose:
  1578.                Terminates a connection.
  1579.                Is used by the system to terminate all connections.
  1580.  
  1581.             restrictions:
  1582.                You should always pass the handle that you received from
  1583.                the ESTABLISH method as the JOBJ and not pass any
  1584.                second argument (defaults to zero).
  1585.                You may not run this method asynchronously to the caller.
  1586.  
  1587.             function:
  1588.                If flags are NULL, then simply removes the connection
  1589.                that that handle symbolizes.  If this is the last
  1590.                connection, and if the AUTOREMOVE flag was specified in
  1591.                the INIT method, then the Director is Remove()'d from the
  1592.                system.
  1593.  
  1594.                Otherwise, if SHADOW_SORT is specified, the first handle
  1595.                on the list that is stored as being authorized by the
  1596.                passed object is terminated.
  1597.  
  1598.                Uses RemoveClassWatcher() or RemoveWatcherNode()
  1599.                internally to remove the watcher from the watching-list.
  1600.                Please see the AutoDocs for more information on these
  1601.                functions.
  1602.  
  1603.             example:
  1604.                see the METH_DIRECTOR_ESTABLISH method example for this
  1605.                class above.
  1606.  
  1607.  
  1608.          METH_DIRECTOR_NOTIFY
  1609.             run as:
  1610.                function in invoker's process.
  1611.  
  1612.             arguments:
  1613.                long -- Flags specifying what changed.
  1614.                APTR -- A pointer to the WatchedVariable that caused the
  1615.                         notification.  Note: this pointer will NOT be
  1616.                         valid if sent ASYNC!  This implies that the method
  1617.                         to which notification is sent might also inherit
  1618.                         nonsense in this value, so don't do anything
  1619.                         brash with the NOTIFY method!
  1620.                APTR -- The new node/value of the WatchedVariable.  Once
  1621.                         again, ASYNC causes nightmares.
  1622.                JSTR -- The name of the new node, if specified.
  1623.  
  1624.             purpose:
  1625.                A change occurred someplace that this watcher was watching.
  1626.                The system calls this function with the correct flags and
  1627.                arguments, depending on the type of change that occurred.
  1628.  
  1629.             restrictions:
  1630.                You may not run this method asynchronously to the caller.
  1631.                You should not have to call this method directly.  Instead,
  1632.                use the library function call, WatcherDispatch().
  1633.  
  1634.             function:
  1635.                If this Director is interested in the particular piece of
  1636.                information being broadcast, then notification is sent out.
  1637.  
  1638.                The following are the flags that effect this control.
  1639.                These are the flags in the lower 16bits of the flags field
  1640.                sent to the INIT function.
  1641.  
  1642.                   /*
  1643.                    * Match either.
  1644.                    */
  1645.                   #define W_CHANGE_ZERO      1
  1646.                   #define W_CHANGE_NON_ZERO  2
  1647.                   #define W_CHANGE_VALUE     3
  1648.  
  1649.                   /*
  1650.                    * Match exactly
  1651.                    */
  1652.                   #define W_NODE             4
  1653.                   #define W_WATCH_CHANGE     8
  1654.                   #define W_REMOVE           16
  1655.                   #define W_INSERT           32
  1656.  
  1657.                   /*
  1658.                    * Control matching.
  1659.                    */
  1660.                   #define W_MATCH            64
  1661.                   #define W_MATCH_VALUE      W_MATCH
  1662.                   #define W_SECOND           128
  1663.  
  1664.                   #define W_MATCH_FIRST      W_MATCH
  1665.                   #define W_MATCH_SECOND     (W_SECOND | W_MATCH)
  1666.  
  1667.                   #define W_INSERT_NODE      (W_NODE | W_INSERT)
  1668.                   #define W_REMOVE_NODE      (W_NODE | W_REMOVE)
  1669.  
  1670.                   #define W_INSERT_WATCHER   (W_WATCH_CHANGE | W_INSERT)
  1671.                     /* Not valid during... */
  1672.                   #define W_REMOVE_WATCHER   (W_WATCH_CHANGE | W_REMOVE)
  1673.                     /* ... INIT[]/DESTROY[]  */
  1674.  
  1675.                The first three flags apply only to non-(list/tree)
  1676.                variables.  IE: the simple longword type of watched
  1677.                variable -- the WatchedValue.  W_CHANGE_ZERO is for when
  1678.                the variable changes to a zero, W_CHANGE_NON_ZERO is for
  1679.                when a variable changes to a non-zero, and W_CHANGE_VALUE
  1680.                is for when either happens.  Note that the value may have
  1681.                already been zero or non-zero.  You may use the
  1682.                W_WATCH_CHANGE to indicate that you don't want to hear
  1683.                about updates to the variables that don't actually CHANGE
  1684.                the value that has already been stored [V5].
  1685.  
  1686.                W_NODE is for any addition or removal of nodes from lists or
  1687.                trees.  W_WATCH_CHANGE, in conjunction with W_INSERT and
  1688.                W_REMOVE, sends notification out when a watcher is added.
  1689.                A watcher can get notification when it adds itself, but not
  1690.                when it removes itself -- sorry, you'll have to use two
  1691.                watchers for that....  W_REMOVE and W_INSERT control
  1692.                whether you want notification when something is added or
  1693.                removed to/from the list/tree.
  1694.  
  1695.                W_MATCH is used for a simple matching capability.  You can
  1696.                watch for a particular object to be removed from the tree,
  1697.                or added to the tree, or whatever....  For example, you
  1698.                might want to know when a -particular- class was created.
  1699.  
  1700.                W_MATCH_FIRST uses the value sent to the INIT function as
  1701.                the value of, either:
  1702.                   (a) the value that the WatchedVariable should take on.
  1703.                   (b)the address of the object added to a list/tree.
  1704.                depending on the type of WatchedVariable.
  1705.  
  1706.                W_MATCH_SECOND uses the value sent to the INIT function
  1707.                as the address of a string which would be the name under
  1708.                which the node is added to the list/tree.
  1709.  
  1710.             example:
  1711.                You should not have to call this method directly.  Instead,
  1712.                use the library function call, WatcherDispatch().
  1713.  
  1714.  
  1715.                /*
  1716.                 * This is roughly the definition of
  1717.                 * RemoveWatchedTreeStringNode()
  1718.                 *
  1719.                 * node is the node to remove
  1720.                 */
  1721.                UseObject(node);
  1722.  
  1723.                if (ret = RemoveTreeStringNode(&(bt->wv_value), node, name))
  1724.                {
  1725.                   WatcherDispatch(W_REMOVE_NODE,
  1726.                                   (struct WatchedValue *)bt,
  1727.                                   node,
  1728.                                   name);
  1729.                }
  1730.                DropObject(node);
  1731.                return ret;
  1732.  
  1733.  
  1734.       Modified Methods
  1735.          METH_DESTROY
  1736.             run as:
  1737.                function in invoker's process.
  1738.  
  1739.             arguments:
  1740.                none
  1741.  
  1742.             purpose:
  1743.                METH_DESTROY frees an object.
  1744.                When DropObject() notices that the usecount has fallen to
  1745.                zero, it invokes the METH_DESTROY method on the object.
  1746.  
  1747.             restrictions:
  1748.                You should never invoke this method yourself!
  1749.                This method is always invoked by DropObject()!
  1750.  
  1751.             function:
  1752.                Name is Drop()'d from the ATTR_MANAGER node->mnn_name field.
  1753.                If W_SECOND was specified during the METH_INIT, the
  1754.                node->mnn_value is Drop()'d as well.
  1755.                Method is then routed to the superclass.
  1756.                If invoked asynchronously, the object pointer is
  1757.                transferred out of the msg.
  1758.  
  1759.             example:
  1760.                See example under META_CLASS
  1761.  
  1762.  
  1763.          METH_INIT
  1764.             run as:
  1765.                function in invoker's process.
  1766.  
  1767.             arguments:
  1768.                JSTR -- the name of the object.
  1769.                JOBJ -- object to send the notification method to.
  1770.                JSTR -- the notification method.
  1771.                long -- various flags controlling the type of watcher
  1772.                         (object or class), the function of the
  1773.                         notification, etc.
  1774.                long -- optional value for the W_SECOND or W_MATCH_FIRST
  1775.                         flags.  If W_SECOND is specified in the flags
  1776.                         field, then this method cannot be invoked
  1777.                         asynchronously, because this would be a pointer
  1778.                         to a string....
  1779.  
  1780.                returns the initialized object, or NULL on failure.
  1781.  
  1782.             purpose:
  1783.                Initializes the object and makes it possible to
  1784.                ESTABLISH connections with it.
  1785.  
  1786.             restrictions:
  1787.                Sending this method asynchronously may be dangerous,
  1788.                depending on what type the last argument to the method is.
  1789.                Care must be taken if you want to send this as an
  1790.                asynchronous method.
  1791.  
  1792.             function:
  1793.                As with all INIT functions, if the object is not
  1794.                successfully INIT'd, the object is UseObject()'d and
  1795.                DropObject()'d, resulting in an invocation of the
  1796.                METH_DESTROY function.  Usually, the party interested in
  1797.                receiving notification is UseObject()'d and stored in the
  1798.                ATTR_MANAGER's node->mnn_method and node->mnn_object.
  1799.                The name is used and put into the structure at
  1800.                node->mnn_name.  If  W_SECOND is specified in the flags
  1801.                field, the optional value is treated as a string.  In
  1802.                addition, this function parcels the long flags value into
  1803.                its pieces.  The bottom 16 bits become the instrument that
  1804.                controls when the Director sends out its notification.
  1805.                The next eight bits has only one flag allocated that
  1806.                distinguish between SHADOW_OBJECT and SHADOW_CLASS types
  1807.                of Directors.  (One watches a particular object, the other
  1808.                watches all objects in a class.)  The last eight bits
  1809.                control the working of the internal resource tracking.
  1810.                One bit is the SHADOW_AUTOREMOVE.  When specified, the
  1811.                last connection TERMINATion causes a METH_REMOVE to be sent
  1812.                to itself.  The other bit is the SHADOW_AUTOBREAK flag.
  1813.                When it is specified, the REMOVE method automatically
  1814.                TERMINATEs all connections.  Unless you do something very
  1815.                bizarre, you should specify both bits.  An internal bit
  1816.                (SHADOW_REMOVED) prevents an infinite recursion when both
  1817.                bits are specified.
  1818.  
  1819.                You can control the notification so that it occurs only on
  1820.                specific types of events.  This is controlled by the first
  1821.                16 bits of the 'flags' parameter.  The W_* flags which
  1822.                control the notification restriction are specified in the
  1823.                method immediately above this one.
  1824.  
  1825.                Method then is routed to the superclass.
  1826.  
  1827.             example:
  1828.                see the METH_DIRECTOR_ESTABLISH method example for this
  1829.                class above.
  1830.  
  1831.  
  1832.          METH_REMOVE
  1833.             run as:
  1834.                function in invoker's process.
  1835.  
  1836.             arguments:
  1837.                none
  1838.  
  1839.             purpose:
  1840.                Removes the object from the system and makes it impossible
  1841.                to ESTABLISH further connections.
  1842.                May also disengage any current connections if
  1843.                SHADOW_AUTOBREAK was specified during the METH_INIT.
  1844.  
  1845.             restrictions:
  1846.                none
  1847.  
  1848.             function:
  1849.                If the Director had its SHADOW_AUTOBREAK specified, all
  1850.                connections are TERMINATEd.  The notification destination
  1851.                object and method are Drop()'d, cleared.
  1852.                Method is then routed to the superclass.
  1853.  
  1854.             example:
  1855.                see the METH_DIRECTOR_ESTABLISH method example for this
  1856.                class above.
  1857.  
  1858.  
  1859.  
  1860.    Class:         PATCHER_CLASS
  1861.    Superclass:    ROOT_CLASS
  1862.    Include File:  <shadow/method.h>
  1863.  
  1864.    The class that creates patches on pre-existing methods.
  1865.  
  1866.       Attributes:
  1867.          ATTR_METHODHANDLER -- struct MethodHandler followed by a class
  1868.                                 pointer which indicates the class that was
  1869.                                 patched.  [Attribute is located at address
  1870.                                 offset of eight from the object, this
  1871.                                 behaviour is depended on by the OS.]
  1872.  
  1873.       Modified Methods:
  1874.          METH_DESTROY
  1875.             run as:
  1876.                function in invoker's prcoess.
  1877.  
  1878.             arguments:
  1879.                none
  1880.  
  1881.             purpose:
  1882.                METH_DESTROY frees an object.
  1883.                When DropObject() notices that the usecount has fallen to
  1884.                zero, it invokes the METH_DESTROY method on the object.
  1885.  
  1886.             restrictions:
  1887.                You should never invoke this method yourself!
  1888.                This method is always invoked by DropObject()!
  1889.  
  1890.             function:
  1891.                Drop()s the procObject, defnObject and MethodID of the
  1892.                patch.  Invokes the superclass, then transfers the object
  1893.                from the msg so that it will work properly when/if invoked
  1894.                asynchronously.
  1895.  
  1896.             example:
  1897.                See example under META_CLASS
  1898.  
  1899.  
  1900.          METH_INIT
  1901.             run as:
  1902.                function in invoker's process.
  1903.  
  1904.             arguments:
  1905.                APTR -- A MethodTag.  This does NOT cause problems for
  1906.                         ASYNC methods....
  1907.                JOBJ -- class to patch, or an object of that class; in
  1908.                         which case, unless the object has an
  1909.                         ATTR_PATCHEDVERBS attribute, the class of the
  1910.                         passed object, not the passed object, is patched.
  1911.  
  1912.                returns the initialized object, or NULL on failure.
  1913.  
  1914.             purpose:
  1915.                Initializes the object and installs the patch.
  1916.  
  1917.             restrictions:
  1918.                You should be prepared to handle the patched method before
  1919.                invoking this method.
  1920.  
  1921.             function:
  1922.                Usually, the method to be patched is found (failure to
  1923.                find the method in the class requested causes the patch
  1924.                to fail -- DOES NOT CHECK superclasses!), procObject and
  1925.                defnObject in the MethodTag fields are Use()'d and put
  1926.                into the ATTR_METHODHANDLER.  MethodID is also Use()'d.
  1927.                In addition, all other MethodTag information is copied into
  1928.                the MethodHandler structure.  Class information is saved in
  1929.                the patched-class field -- this is NOT Use()'d!  Patch is
  1930.                inserted.
  1931.                Method is then routed to the superclass.
  1932.  
  1933.             example:
  1934.                /*
  1935.                 * The patch data (usually a global)
  1936.                 *
  1937.                 * This method returns stuff in both d0 and d1, hence its
  1938.                 *  prototype as 'double'.  If D1 is non-zero, the patches
  1939.                 *  with lower priority (this includes the method itself)
  1940.                 *  are called.  If D1 is zero, the method invocation
  1941.                 *  process is terminated.
  1942.                 */
  1943.                extern double PreTestMethod(METHOD_ARGS);
  1944.  
  1945.                METHOD_TAG preMethod =
  1946.                            {
  1947.                               "Method TEST",
  1948.                               NULL, NULL,
  1949.                               INVOKE_SYNC,
  1950.                               METH_FLAG_CHECK_CONTINUE |
  1951.                               METH_FLAG_CLASS,
  1952.                               1, /* The priority */
  1953.                               (METHODFUNCTYPE)PreTestMethod, NULL
  1954.                            };
  1955.                /*
  1956.                 * Add a method patch.
  1957.                 * Note we CANNOT use SetupMethodTags!
  1958.                 */
  1959.                preMethod.mtag_procObject = dosTaskClass;
  1960.                preMethod.mtag_defnObject = CurrentProcess();
  1961.  
  1962.                prePatch = CreateInstance(NULL, PATCHER_CLASS,
  1963.                                                META_CLASS,
  1964.                                                &preMethod,
  1965.                                                my_dos_class, /*
  1966.                                                               * Actual
  1967.                                                               * instance
  1968.                                                               * of
  1969.                                                               * class.
  1970.                                                               */
  1971.                                                METHOD_END);
  1972.                .
  1973.                .
  1974.                .
  1975.                /*
  1976.                 * Cleanup
  1977.                 */
  1978.                RemoveObject(prePatch);
  1979.  
  1980.  
  1981.          METH_REMOVE
  1982.             run as:
  1983.                function in invoker's process.
  1984.  
  1985.             arguments:
  1986.                none
  1987.  
  1988.             purpose:
  1989.                Removes the object and the patch from the system.
  1990.  
  1991.             restrictions:
  1992.                none
  1993.  
  1994.             function:
  1995.                Patch is removed from the ATTR_PATCHEDVERBS list of the
  1996.                class that this object is patching.
  1997.                Method is then routed to the superclass.
  1998.  
  1999.             example:
  2000.                see the METH_INIT method example for this class above.
  2001.  
  2002.  
  2003.    Class:         PROCESS_CLASS
  2004.    Superclass:    ROOT_CLASS
  2005.    Include File:  <shadow/process.h>
  2006.  
  2007.    The class that creates processes.
  2008.  
  2009.       Attributes:
  2010.          ATTR_JAZZPROCESS   -- struct JazzProcess.  Again, the system expects
  2011.                                 to find this attribute at offset 8.  Do not
  2012.                                 hack around and move it, please.
  2013.          ATTR_RESOURCETREE  -- Watched binary tree that you can store
  2014.                                 your resources on.
  2015.          ATTR_RESOURCESTACK -- Watched list that you can store last
  2016.                                 minute removal resources.  Freed only
  2017.                                 during The DISASSOCIATE method.
  2018.       New Methods:
  2019.          METH_PROC_ASSOCIATE
  2020.             run as:
  2021.                function in invoker's process.
  2022.  
  2023.             purpose:
  2024.                Completes the initialization of the object and allocates
  2025.                the process' ports.  Certain things need to be allocated
  2026.                inside of a process' context (like signals, ports, etc.),
  2027.                so this method exists to allow you to do our allocation
  2028.                at this time.
  2029.  
  2030.             restrictions:
  2031.                This method should only be invoked in the context of a
  2032.                currently running process.  The METH_INIT handles
  2033.                this correctly for new processes, InitOOProgram()
  2034.                handles a default version for the programs you start
  2035.                up.
  2036.                If compiling with the small data model, you must call
  2037.                either the equivalent of geta4() or prototype your
  2038.                method-function with the __saveds keyword.
  2039.  
  2040.             arguments:
  2041.                JSTR -- name of the current process.  Defaults to
  2042.                         FindTask(NULL)->tc_node.ln_Name
  2043.                TASK -- pointer to the task.  Defaults to
  2044.                         FindTask(NULL).  Needs to be run in the
  2045.                         that task's frame anyway, because Signals
  2046.                         for message ports are allocated....
  2047.  
  2048.                returns object  which should NOT be DROP()'d!  This is
  2049.                safe because the method can only be invoked in that
  2050.                process to begin with....
  2051.  
  2052.             function:
  2053.                Creates a SHADOW process object for a process that already
  2054.                exists.  Stores the object into task->tc_UserData.
  2055.                Creates ports and synchronous messages for this
  2056.                process.
  2057.                Sends the METH_INIT method to the class' superclass -- the
  2058.                ROOT_CLASS.
  2059.  
  2060.             example:
  2061.                /*
  2062.                 * This is roughly the source to InitOOProgram()
  2063.                 */
  2064.  
  2065.                procClass = FindShadowClass(PROCESS_CLASS);
  2066.                myProc = DoShadow(procClass,
  2067.                                  NULL,
  2068.                                  METH_CREATE,
  2069.                                  METHOD_END);
  2070.                myProc = DoShadow(myProc,
  2071.                                  NULL,
  2072.                                  METH_PROC_ASSOCIATE,
  2073.                                  name,
  2074.                                  METHOD_END);
  2075.                DropObject(procClass);
  2076.  
  2077.                .
  2078.                .
  2079.                .
  2080.  
  2081.                /*
  2082.                 * Don't forget to call the RemoveCurrentProgram()
  2083.                 * function or some equivalent during cleanup!
  2084.                 */
  2085.  
  2086.  
  2087.          METH_PROC_DISASSOCIATE
  2088.             run as:
  2089.                function in process associated with the object that
  2090.                the method is being invoked on.
  2091.  
  2092.             arguments:
  2093.                none
  2094.  
  2095.             purpose:
  2096.                Completes the process end of the process destruction.
  2097.                Certain items under AmigaDOS must be freed in the
  2098.                process that allocated them -- like ports and signals.
  2099.                This method allows you someplace to put such items.
  2100.  
  2101.             restrictions:
  2102.                This is a system invoked method similar to METH_DESTROY.
  2103.                You may subclass this method, but do not call it.
  2104.                Again, be careful about the small data model (see above
  2105.                method).
  2106.  
  2107.             function:
  2108.                Shuts various system ports, handles remaining messages,
  2109.                leaves the ports, deletes the synchronous message.
  2110.                Removes all the resources (RemoveResources(object, TRUE)).
  2111.                Deletes the process name.
  2112.                When the method returns, the system will call the
  2113.                METH_DESTROY on the process object's superclass to complete
  2114.                the object destruction.  The process will then return to
  2115.                AmigaDOS.
  2116.             example:
  2117.                You should never call this function.
  2118.                Process cleanup is automatic when a -created- program
  2119.                exits.  When an Amiga-launched app ends, the programmer
  2120.                should call RemoveCurrentProgram().
  2121.  
  2122.  
  2123.          METH_PROC_HANDLER
  2124.             run as:
  2125.                function in process associated with the object that
  2126.                the method is being invoked on.
  2127.  
  2128.             arguments:
  2129.                none
  2130.  
  2131.             purpose:
  2132.                Handles all incoming SHADOW messages.  You can subclass
  2133.                this and override this behaviour to include intercepting
  2134.                Intuition events as well....
  2135.  
  2136.             restrictions:
  2137.                This method should only be invoked in the context of a
  2138.                currently running process.  The METH_INIT handles
  2139.                this correctly for new processes, no handling is done
  2140.                for your own program -- you decide where to finally
  2141.                wait for all the mehods....
  2142.  
  2143.                If compiling with the small data model, you must call
  2144.                either the equivalent of geta4() or prototype your
  2145.                method-function with the __saveds keyword.
  2146.  
  2147.             function:
  2148.                Processes all SHADOW messages.
  2149.                Leaves when ^C is detected.
  2150.  
  2151.             example:
  2152.                From <shadow/shadow_proto.h>
  2153.                DoShadow(CurrentProcess(), NULL, METH_PROC_HANDLER,
  2154.                         METHOD_END);
  2155.                The METH_PROC_HANDLER is automatically called for
  2156.                   SHADOW-launched prcesses.
  2157.  
  2158.  
  2159.       Modified Methods:
  2160.          METH_DESTROY
  2161.             run as:
  2162.                function in invoker's process.
  2163.  
  2164.             arguments:
  2165.                none
  2166.  
  2167.             purpose:
  2168.                METH_DESTROY frees an object.
  2169.                When DropObject() notices that the usecount has fallen to
  2170.                zero, it invokes the METH_DESTROY method on the object.
  2171.  
  2172.             restrictions:
  2173.                You should never invoke this method yourself!
  2174.                This method is always invoked by DropObject()!
  2175.                This method MUST ALWAYS BE INVOKE_CALL!  Never
  2176.                subclass this method to be INVOKE_SYNC or INVOKE_MSG_SYNC.
  2177.  
  2178.             function:
  2179.                ATTR_RESOURCETREE is freed.
  2180.  
  2181.                The SHADOW_PROC_FLAGS_DESTROYED bit is set to inform the
  2182.                process that it should really go away.  A ^C is sent
  2183.                to the associated process to tell it to go away.
  2184.                Upon receipt of these signals, the METH_PROC_HANDLER
  2185.                should return.  The system will then call the
  2186.                METH_PROC_DISASSOCIATE and then the METH_DESTROY on the
  2187.                superclass of process class, the root class.
  2188.  
  2189.                If there is no associated process (ie: if the METH_INIT
  2190.                didn't work properly), the superclass is called directly.
  2191.  
  2192.             example:
  2193.                See example under META_CLASS
  2194.  
  2195.  
  2196.          METH_INIT
  2197.             run as:
  2198.                function in invoker's process.
  2199.             arguments:
  2200.                JSTR -- name of the process to create.
  2201.                JOBJ -- The parent object.  if no parent object, the
  2202.                         calling process is used as the parent.
  2203.                SEMF -- an optional semaphore to own shared by the started
  2204.                         process.  Semaphore is Release()'d when task exits.
  2205.                TAGL -- a NULL terminated array of struct TagItem to send to
  2206.                         the CreateNewProc invok.  If the INIT fails AFTER
  2207.                         the process is created, the tags' ti_Tag are set
  2208.                         to TAG_IGNORE, so you don't have to free the
  2209.                         resources that might be in the TAGL if the process
  2210.                         fails to be created.  (In fact, the ti_Tags are
  2211.                         set to TAG_IGNORE even if the process successfully
  2212.                         opens.)
  2213.                APTR -- Pointer to an optional ProcessInitFrame.  This is
  2214.                         used as an override array to the ASSOCIATE method
  2215.                         to allow the METH_INIT to initialize other classes
  2216.                         of processes in an arbitrarily coplex manner.
  2217.                APTR -- Pointer to an optional ProcessHandlerFrame.  This is
  2218.                         used as an override array to the HANDLER method
  2219.                         to allow METH_INIT to initialize other classes of
  2220.                         processes in an arbitrarily complex manner.
  2221.  
  2222.                returns the initialized object, or NULL on failure.
  2223.  
  2224.             purpose:
  2225.                Create a new process and get the process up and running.
  2226.  
  2227.             restrictions:
  2228.                If the last two fields are used, this function should
  2229.                not be called asynchronously.  The Init and Handler Frames
  2230.                may grow arbitrarily large in size to account for
  2231.                HANDLER or ASSOCIATE methods that require a large number
  2232.                of arguments.
  2233.                If you pass resources in the tags (like file handles), this
  2234.                function should, again, not be called asynchronously.
  2235.  
  2236.             function:
  2237.                Using the two optional frames (and the local default
  2238.                frames), the ASSOCIATE and HANDLER methods are preparsed
  2239.                and sent to the newly created process in the form of
  2240.                messages (allowing asynchronous, safe startups).
  2241.  
  2242.                The superclass is NOT called, that's done inside of
  2243.                the PROC_ASSOCIATE method.
  2244.  
  2245.                Semaphore Obtain()'d shared, process is created, and various
  2246.                magic done to ensure a safe startup between processes.
  2247.  
  2248.                Will set all ti_Tag elements to TAG_IGNORE if process is
  2249.                successfully started, even if process subsequently shuts
  2250.                down due to a startup error.  This allows you to free
  2251.                resources correctly (hopefully) when process' fail to start
  2252.                properly, independent upon whether it was the
  2253.                CreateNewProc() invocation that failed, or something else....
  2254.  
  2255.             example:
  2256.                /*
  2257.                 * This example demonstrates how to get
  2258.                 *  the INIT method to invoke a subclassed
  2259.                 *  METH_PROC_HANDLER with arguments different from the
  2260.                 *  default.  In this case, the METH_PROC_HANDLER is
  2261.                 *  responsible for defining a new class, so the class
  2262.                 *  creation arguments are sent into the METH_PROC_HANDLER.
  2263.                 *
  2264.                 * Also note, this is code from the METH_INIT of this
  2265.                 *  process-class, so the METH_INIT is actually sent
  2266.                 *  on to the superclass.
  2267.                 */
  2268.                struct MyHandlerFrame {
  2269.                   struct ProcessHandlerFrame mf_handlerArgs;
  2270.                   char                       *mf_newName;
  2271.                   struct MethodTag           *mf_methods;
  2272.                   struct AttributeTag        *mf_attrs;
  2273.                   void                       *END;
  2274.                } mhf;
  2275.  
  2276.                mhf.mf_handlerArgs.phf_methodID = NULL;  /* default! */
  2277.                /*
  2278.                 * New arguments for the subclassed METH_PROC_HANDLER!
  2279.                 */
  2280.                mhf.mf_handlerArgs.phf_args[0] = paramClassName;
  2281.                mhf.mf_newName = newName;
  2282.                mhf.mf_methods = methods;
  2283.                mhf.mf_attrs = attrs;
  2284.                mhf.END =  METHOD_END;
  2285.  
  2286.                process = DoShadow(object, class->meta_superClass,
  2287.                                           MethodID,
  2288.                                           processName,
  2289.                                           NULL, NULL, NULL,
  2290.                                           NULL,
  2291.                                           &mhf,
  2292.                                           METHOD_END);
  2293.  
  2294.                return process;
  2295.  
  2296.                .
  2297.                .
  2298.                .
  2299.  
  2300.                /*
  2301.                 * Cleanup!
  2302.                 */
  2303.                RemoveObject(process);
  2304.  
  2305.  
  2306.          METH_REMOVE
  2307.             run as:
  2308.                function in process associated with the object that
  2309.                the method is being invoked on.
  2310.  
  2311.             arguments:
  2312.                none
  2313.  
  2314.             purpose:
  2315.                Removes the process object from the system.
  2316.  
  2317.             restrictions:
  2318.                none
  2319.  
  2320.             function:
  2321.                Sets the Remove flag.
  2322.                Method is then routed to the superclass.
  2323.                A call to RemoveResources(object, FALSE) is made.
  2324.  
  2325.             example:
  2326.                see the METH_INIT method example for this class above.
  2327.